#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <limits.h>
#include <fcntl.h>
#include <sys/time.h>
#include <sys/types.h>
#include <sys/stat.h>
 
#include "data_type.h"
#include "cube.h"
#include "cube_define.h"
#include "cube_record.h"

#include "tcm_constants.h"
#include "tcm_structures.h"
#include "tcmfunc.h"
#include "tcm_view.h"
#include "tcmview_server.h"
// add para lib_include
int tcmview_server_init(void * sub_proc, void * para)
{
	int ret;
	// Init Tcm Func
//	ret=TCM_LibInit();

	// add yorself's module init func here
	return 0;
}
int tcmview_server_start(void * sub_proc, void * para)
{
	int ret;
	void * recv_msg;
	int type;
	int subtype;
	// add yorself's module exec func here
	sleep(1);
//	proc_get_ekpub(sub_proc,NULL);

	while(1)
	{
		usleep(time_val.tv_usec);
		ret=ex_module_recvmsg(sub_proc,&recv_msg);
		if(ret<0)
			continue;
		if(recv_msg==NULL)
			continue;
		type=message_get_type(recv_msg);
		subtype=message_get_subtype(recv_msg);
		if(!memdb_find_recordtype(type,subtype))
		{
			printf("message format (%d %d) is not registered!\n",
			message_get_type(recv_msg),message_get_subtype(recv_msg));
			continue;
		}
		if((type==TYPE(TCM_OBJECT_VIEW))&&(subtype==SUBTYPE(TCM_OBJECT_VIEW,NODE)))
		{
			ret=proc_store_nodeinfo(sub_proc,recv_msg);
		}
	
		if((type==TYPE(TCM_OBJECT_QUERY))&&(subtype==SUBTYPE(TCM_OBJECT_QUERY,NODE)))
		{
			ret=proc_send_nodeinfo(sub_proc,recv_msg);
		}
		else if((type==TYPE(TCM_OBJECT_QUERY))&&(subtype==SUBTYPE(TCM_OBJECT_QUERY,TCM)))
		{
			ret=proc_send_tcminfo(sub_proc,recv_msg);
		}
		else if((type==TYPE(TCM_OBJECT_QUERY))&&(subtype==SUBTYPE(TCM_OBJECT_QUERY,PRIVATEKEY)))
		{
			ret=proc_send_privatekeyinfo(sub_proc,recv_msg);
		}
		else if((type==TYPE(TCM_OBJECT_QUERY))&&(subtype==SUBTYPE(TCM_OBJECT_QUERY,PUBLICKEY)))
		{
			ret=proc_send_publickeyinfo(sub_proc,recv_msg);
		}
	}
	return 0;
}

int proc_store_nodeinfo(void * sub_proc,void * recv_msg)
{
	int ret=0;
	int fd;

	BYTE local_uuid[DIGEST_SIZE];	
	
	BYTE Buf[DIGEST_SIZE*16];
	BYTE NameBuf[DIGEST_SIZE*4];
	UINT32 result;
	DB_RECORD * db_record;
	RECORD(TCM_OBJECT_VIEW,NODE)  *tcm_node;
	void * new_msg;

	printf("begin node query!\n");
	// get the query info
	ret =message_get_record(recv_msg,&tcm_node,0);
	if(ret<0)
		return -EINVAL;

	db_record=memdb_store(tcm_node,TYPE_PAIR(TCM_OBJECT_VIEW,NODE),tcm_node->name);
	if(db_record==NULL)
		return -EINVAL;
	return 0;
}

int proc_send_nodeinfo(void * sub_proc,void * recv_msg)
{
	int ret=0;
	int fd;

	BYTE local_uuid[DIGEST_SIZE];	
	
	BYTE Buf[DIGEST_SIZE*16];
	BYTE NameBuf[DIGEST_SIZE*4];
	UINT32 result;
	DB_RECORD * db_record;
	RECORD(TCM_OBJECT_VIEW,NODE)  *tcm_node;
	RECORD(TCM_OBJECT_QUERY,NODE) *node_query;
	void * new_msg;

	printf("begin node query!\n");
	// get the query info
	ret =message_get_record(recv_msg,&node_query,0);
	if(ret<0)
		return -EINVAL;

	// build output message
	new_msg=message_create(TYPE_PAIR(TCM_OBJECT_VIEW,NODE),recv_msg);	
	if(new_msg==NULL)
		return -EINVAL;
	int count=0;
	RECORD(MESSAGE,NUMBER) number;
	
	if(node_query->name[0]==0)
	{
		if(Memcmp(node_query->uuid,EMPTY_UUID,DIGEST_SIZE)==0)
		{
			tcm_node=memdb_get_first_record(TYPE_PAIR(TCM_OBJECT_VIEW,NODE));
			while(tcm_node!=NULL)
			{
				ret=message_add_record(new_msg,tcm_node);
				if(ret<0)
					return ret;
				number.number=count++;
				tcm_node=memdb_get_next_record(TYPE_PAIR(TCM_OBJECT_VIEW,NODE));
				if(tcm_node==NULL)
					number.number=-count;
				ret=message_add_expand_data(new_msg,TYPE_PAIR(MESSAGE,NUMBER),&number);
				if(ret<0)
					return ret;
				
				if(tcm_node !=NULL)
				{
					ret=ex_module_sendmsg(sub_proc,new_msg);
					if(ret<0)
						return ret;
                                	printf("send one node info!\n");
                                	new_msg=message_create(TYPE_PAIR(TCM_OBJECT_VIEW,NODE),recv_msg);
                                	if(new_msg==NULL)
                                        	return -EINVAL;
				}
			}		
		}
		else
		{
			db_record=memdb_find_first(TYPE_PAIR(TCM_OBJECT_VIEW,NODE),"uuid",node_query->uuid);
			if(db_record!=NULL)
			{
				tcm_node=db_record->record;
				if(tcm_node!=NULL)
				{
					ret=message_add_record(new_msg,tcm_node);
					if(ret<0)
						return ret;
				}
			}
		}
	}		
	else
	{
		db_record=memdb_find_first(TYPE_PAIR(TCM_OBJECT_VIEW,NODE),"name",node_query->name);
		if(db_record!=NULL)
		{
			tcm_node=db_record->record;
			if(tcm_node!=NULL)
			{
				ret=message_add_record(new_msg,tcm_node);
				if(ret<0)
					return ret;
			}
		}
	}

	// Output node info
	
	ret=ex_module_sendmsg(sub_proc,new_msg);
	return ret;
}

int proc_send_tcminfo(void * sub_proc,void * recv_msg)
{

}
int proc_send_privatekeyinfo(void * sub_proc,void * recv_msg)
{

}
int proc_send_publickeyinfo(void * sub_proc,void * recv_msg)
{

}
